﻿// ==UserScript==
// @name          转换riameeting.com视频教程字幕到SRT字幕格式
// @namespace     http://webflash.cnblogs.com
// @description   使用本工具要确保整个视频的播放过程中没有出现缓冲的情况，建议先等视频加载完或加载一半以上再从头开始播放。从头开始播放请马上点击“开始获取字幕”按钮，确保时间的同步。
// @include       http://www.riameeting.com/node/*
// ==/UserScript==

//全局在跑的播放进度时间，单位：秒
var time = 0;
var timer = null;
//本视频字幕行数，作为结束字幕获取的依据
var srtSize = 0;
//当前要检查的字幕行，用于检测这一行字幕的进入与出去时间
var checkStepNum = 1;
var tempEnterTime = 0;

/**
 * 初始化函数
 */
function init()
{
    creatDom();
    $('startBtn').addEventListener('click', startGetSrt, false);
    $('srtToolState').innerHTML = '等待开始获取字幕，点击“开始获取字幕”按钮开始获取字幕后要确保视频播放过程中不出现缓冲情况';
}

/**
 * 创建本工具HTML UI
 */
function creatDom()
{
    var div = document.createElement('div');
    div.innerHTML = '<div id="getFlvSrt" style="width:100%; background:#CDE1F7; border-bottom:1px solid #BFC4CF; padding:5px 10px"><span id="showTime" style="font-family:Arial">00:00:00</span>　<input id="startBtn" type="button" value="开始获取字幕" />　<span id="srtToolState" style="color:#24375B"></span><br /><textarea id="outputSrt" style="width:60%" rows="5"></textarea></div>';
    //在视频播放器上方显示这个工具的界面
    var videoDiv = $('video_container');
    if (videoDiv)
        videoDiv.parentNode.insertBefore(div, videoDiv);
}

/**
 * 设置字幕总记录数，作为结束字幕获取的条件
 */
function setSrtSize()
{
    var srtList = $('captionsArea').getElementsByTagName('li');
    srtSize = srtList.length;
}

/**
 * 添加一行字幕到文本框
 * @param {Int} step 第几个或第几行字幕
 * @param {Int} enterTime 字幕开始时间（单位：秒）
 * @param {Int} exitTime 字幕结束时间（单位：秒）
 * @param {String} title 字幕内容
 */
function addOneLineSrt(step, enterTime, exitTime, title)
{
    $('outputSrt').innerHTML += step + '\n' + timeFormat(enterTime) + ',000 --> ' + timeFormat(exitTime) + ',000\n{\\fn黑体\\fs10}\n' + forceWrap(title, 35) + '\n\n';
    //使文本框滚动条滚动至底部
    $('outputSrt').scrollTop = $('outputSrt').scrollHeight;
}

/**
 * 开始获取字幕
 */
function startGetSrt()
{
    if ($('captionsArea')) 
    {
		//以下变量重置可实现中途如果发现字幕获取出错，可把视频播放进度拉回起点，点击“开始获取字幕”按钮重新获取字幕，而无需刷新页面重新加载视频
        time = 0;
        if (timer) 
            window.clearInterval(timer);
        checkStepNum = 1;
        tempEnterTime = 0;
		$('outputSrt').innerHTML = '';
        
        setSrtSize();
        $('startBtn').blur();
        timer = window.setInterval(doGetSrt, 500);
    }
    else 
    {
        //因为存在这样http://www.riameeting.com/node/*地址不是视频播放页，所以作下面判断
        alert('没有在本页面找到字幕列表，这应该不是视频播放页！');
        return false;
    }
    $('srtToolState').innerHTML = '字幕获取中……';
}

/**
 * 获取字幕函数，每500毫秒调用一次（本工具核心方法）
 */
function doGetSrt()
{
    if (checkStepNum > srtSize) 
    {
        window.clearInterval(timer);
        $('showTime').innerHTML = '00:00:00';
        $('srtToolState').innerHTML = '字幕获取完毕，全选文本框字幕内容到新建的记事本文件并另存为srt格式，并保证字幕与视频文件在同一目录并且文件名相同';
        $('outputSrt').select();
    }
    else 
    {
        time += 0.5;
        if (getAttr(checkStepNum, 'class') == 'selected') 
        {
            if (!tempEnterTime) 
                tempEnterTime = time;
            //获取最后一条字幕
            if (checkStepNum == srtSize) 
            {
                addOneLineSrt(checkStepNum, time, time + 5, $(checkStepNum).innerHTML);
                checkStepNum++;
            }
        }
        else 
        {
            addOneLineSrt(checkStepNum, tempEnterTime, time, $(checkStepNum).innerHTML);
            tempEnterTime = 0;
            checkStepNum++;
        }
        $('showTime').innerHTML = timeFormat(time);
    }
}

/**
 * 定义getElementById快捷方式
 * @param {String} objId DOM ID
 * @return {DOM}
 */
function $(objID)
{
    return document.getElementById(objID);
}

/**
 * 按DOM的属性名获取它的属性值
 * @param {DOM|String} elem DOM节点对象或节点ID
 * @param {String} attrName 属性名称
 * @return {String}
 */
function getAttr(elem, attrName)
{
    if (typeof(elem) == 'string' || typeof(elem) == 'number') 
        elem = $(elem);
    return elem.getAttribute(attrName);
}

/**
 * 把播放进度秒数转换为00：00：00这样的格式
 * @param {Int} seconds 已播放总秒数
 * @return {String}
 */
function timeFormat(seconds)
{
    seconds = Math.floor(seconds);
    
    var hours = Math.floor(seconds / 3600);
    seconds -= hours * 3600;
    var minutes = Math.floor(seconds / 60);
    seconds -= minutes * 60;
    
    if (hours.toString().length < 2) 
        hours = '0' + hours;
    if (minutes.toString().length < 2) 
        minutes = '0' + minutes;
    if (seconds.toString().length < 2) 
        seconds = '0' + seconds;
    
    return hours + ':' + minutes + ':' + seconds;
}

/**
 * 强制换行（如果一行字幕过长，两边文本会被隐藏，每行字幕合适长度与字体大小是有关系的）
 * @param {String} text 较长的字符串
 * @param {Int} len 每行长度
 * @return {String}
 */
function forceWrap(text, len)
{
    var str = '';
    for (var i = 0; i < text.length; i++) 
    {
        str += text.substr(i, 1);
        if ((i + 1) % len == 0) 
            str += '\n';
    }
    return str;
}

init();
